/*
 * Copyright (c) Huawei Device Co., Ltd. 2024. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "ar_do.h"
#include "common_utils.h"

namespace OHOS {
namespace SE {
using namespace std;

/*
 * Software that is part of the Secure Element access API, it obtains access
 * rules from the Secure Element and applies those rules to restrict device
 * application access to the various Secure Element applications.
 */
ArDo::ArDo(std::vector<uint8_t> rawData)
    : BerTlv(rawData, AR_DO_TAG)
{
    rawData_ = rawData;
    doTag_ = AR_DO_TAG;
}

ArDo::ArDo(std::vector<uint8_t> payload, bool isPayload)
    : BerTlv(payload, true, AR_DO_TAG)
{
    doTag_ = AR_DO_TAG;
}

ArDo::~ArDo()
{
}

bool ArDo::GetApduArDo(vector<ApduArDo> &retApduArDo)
{
    uint32_t tag;
    if (!GetDoTag(tag) || tag != AR_DO_TAG) {
        return false;
    }
    vector<uint8_t> payload;
    if (!GetDoPayload(payload)) {
        return false;
    }
    // parse refardo from payload
    if (payload.empty() || payload.size() == 0) {
        ErrorLog("No REF_AR_DO.");
        return false;
    }
    uint32_t startIndex = 0;
    uint32_t length = 0;
    std::vector<uint8_t> apduArDoData;
    do {
        // get ApduArDo
        if (payload[startIndex] != APDU_AR_DO_TAG) {
            ErrorLog("invalid ApduArDo header.");
            return false;
        }
        length = payload[startIndex + 1];
        if (payload.size() < startIndex + 1 + length) {
            ErrorLog("invalid ApduArDo length.");
            return false;
        }
        vector<uint8_t> tmpApduArDoData;
        // 2 means header and length
        tmpApduArDoData.assign(payload.begin() + startIndex, payload.begin() + startIndex + length + 2);
        std::string strForApduArDo = CommonUtils::BytesArrayToHexString(&tmpApduArDoData[0], tmpApduArDoData.size());
        InfoLog("strForApduArDo %{public}s. startIndex=%{public}d, length=%{public}d",
            strForApduArDo.c_str(), startIndex, length);
        ApduArDo tmpApduArDo = ApduArDo(tmpApduArDoData);
        retApduArDo.push_back(tmpApduArDo);
        startIndex = startIndex + length + 2; // 2 means header and length
    } while (0);
    return true;
}

}  // namespace SE
}  // namespace OHOS
